package com.xc.quickstart.common.interceptor;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.time.Duration;
import java.time.Instant;

/**
 * @author yinyansheng
 */
@Slf4j
public class LogCglibInterceptor implements MethodInterceptor {

    public Object proxy(Class target) {
        // 为代理类指定需要代理的类，也即是父类
        Enhancer enhancer = new Enhancer();
        // 设置方法拦截器回调引用，对于代理类上所有方法的调用，都会调用CallBack，而Callback则需要实现intercept() 方法进行拦截
        enhancer.setSuperclass(target);
        // 获取动态代理类对象并返回
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Instant begin = Instant.now();

        log.info("[LogCglibInterceptor]调用开始 method:{},args:{}"
                , method.getDeclaringClass().getName() + "." + method.getName()
                , JSON.toJSONString(args));

        Object result = methodProxy.invokeSuper(o, args);

        log.info("[LogControllerAspect]调用结束 method:{},args:{},result:{},cost:{},speed:{}"
                , method.getDeclaringClass().getName() + "." + method.getName()
                , JSON.toJSONString(args)
                , JSON.toJSONString(result)
                , Duration.between(begin, Instant.now()).toMillis()
                , Duration.between(begin, Instant.now()).toMillis() > 500 ? "<<slow>>" : "<<fast>>");

        return result;
    }
}
